#include "pthread_pool.h"



int init_pthread_pool(){

	// sem_init(&sem, 0, 0);
	pthread_cond_init(&cont, NULL);
	//初始化任务列表，和线程池
	struct_pthread_task_head=creat_pthread_task (NULL);
	struct_pthread_pool_head=creat_pthread_pool (0);

	//分离一个线程，监控线程池状态（数量）
	pthread_t pthread_id_monitor;
	int ret=pthread_create(&pthread_id_monitor,NULL,pthread_monitor,NULL);
	if(ret){
		perror("pthread_create fail");
		return -1;
	}
	pthread_detach(pthread_id_monitor);

}


void * pthread_monitor(void * arg){
	printf("pthread_monitor start\n");
	while(1){
		sleep(60);
		int i=0;
		int j=0;
		struct_pthread_pool *p =struct_pthread_pool_head;
		for(i=0;((p->next)!=struct_pthread_pool_head);i++){
			p=p->next;
		}
		if (i>=THRESHOLD){
			for (j = 0; j < (i-MIN_PTHREAD); ++j){
				pthread_all_num--;
				pthread_cancel(struct_pthread_pool_head->next->pthread_id);
				p=struct_pthread_pool_head->next;
				struct_pthread_pool_head->next=p->next;
				free(p);
			}
		}
	}	
}

int pthread_pool_doit(){
	struct_pthread_pool *p =struct_pthread_pool_head;

	int i=0;
	// 计算空闲线程数量
	while(((p->next)!=struct_pthread_pool_head)){
			i++;
			p=p->next;
	}
	if ((i==0)&&(pthread_all_num<=MAX_PTHREAD)){//线程不够增加线程
		pthread_t pthread_id_task;
		if(pthread_create(&pthread_id_task,NULL,pthread_task,NULL)){
			perror("pthread_create fail");
			return -1;
		}
		pthread_all_num++;
		insert_pthread_pool(pthread_id_task);
		pthread_detach(pthread_id_task);
		usleep(1000);
		pthread_cond_signal(&cont);
	}else if(i!=0){//有空闲线程
		pthread_cond_signal(&cont);
	}else{//线程池满，且无空闲
		usleep(1000);
		pthread_pool_doit();
	}
}

void *pthread_task(void *arg){
	
	pthread_mutex_t mutex;
	pthread_mutex_init(&mutex, NULL);
	pthread_t pthread_id=pthread_self();
	struct_pthread_pool *pl=struct_pthread_pool_head;
	struct_pthread_pool *p_tmp=struct_pthread_pool_head;
	printf("pthread start\n");
	while(1){

		pthread_cond_wait(&cont, &mutex);
		//在线程池空闲列表中找到自己的pthread_id	
		while((pl->next->pthread_id)!=pthread_id){
			pl=pl->next;
		}
		p_tmp=pl->next;
		pl->next=p_tmp->next;
		//移除一个任务
		struct_pthread_task *p=struct_pthread_task_head->next;
		struct_pthread_task_head->next=p->next;
		p->func(arg);
		free(p);
		//线程池空闲列表插入自己的pthread_id
		p_tmp->next=struct_pthread_pool_head->next;
		struct_pthread_pool_head->next=p_tmp;
	}
	
}



struct_pthread_task *creat_pthread_task (void* (*function)(void *)){
	struct_pthread_task *p=(struct_pthread_task *)malloc(sizeof(struct_pthread_task));
	p->next=p;
	p->func=function;
	return p;
}

struct_pthread_pool *creat_pthread_pool (pthread_t pthread_id){
	struct_pthread_pool *p=(struct_pthread_pool *)malloc(sizeof(struct_pthread_pool));
	p->next=p;
	p->pthread_id=pthread_id;
	return p;
}

void insert_pthread_task(void* (*function)(void *)){
	struct_pthread_task *p=creat_pthread_task(function);
	p->next=struct_pthread_task_head->next;
	struct_pthread_task_head->next=p;
}

void insert_pthread_pool(pthread_t pthread_id){
	struct_pthread_pool *p=creat_pthread_pool(pthread_id);
	p->next=struct_pthread_pool_head->next;
	struct_pthread_pool_head->next=p;
}

